package com.lipaluma.field.mapper.mapping;

import java.util.List;
import java.util.Locale;

import org.apache.commons.lang.LocaleUtils;

import com.lipaluma.exceptions.CsvParserException;
import com.lipaluma.xml.mapping.XmlFieldMapping;

public class MappingOptions {
	private String pattern;
	private Locale locale;
	private String separator;
	private boolean keepAll;
	
	private String[] trueValues;
	private String[] falseValues;
	private boolean required;
	private boolean trim;
	private boolean eachValueRequired;
	
	public String getPattern() {
		return pattern;
	}
	public Locale getLocale() {
		return locale;
	}
	public String getSeparator() {
		return separator;
	}
	public boolean isKeepAll() {
		return keepAll;
	}

	public String[] getTrueValues() {
		return trueValues;
	}
	
	public String[] getFalseValues() {
		return falseValues;
	}
	
	public boolean isRequired() {
		return required;
	}
	
	public boolean isTrim() {
		return trim;
	}
	
	public boolean isEachValueRequired() {
		return eachValueRequired;
	}
	
	public static Builder builder() {
		return new Builder();
	}
	
	public static class Builder {
		private String pattern;
		private Locale locale;
		private String separator;
		private boolean keepAll;
		private String[] trueValues;
		private String[] falseValues;
		private boolean required;
		private boolean trim;
		private boolean eachValueRequired;

		public Builder by(XmlFieldMapping mapping){
			withPattern(mapping.getPattern());
			withLocale(mapping.getLocale());
			withSeparator(mapping.getSeparator());
			isAllkeeped(mapping.isKeepAll());
			isRequired(mapping.isRequired());
			isTrimed(mapping.isTrim());
			isEachValueRequired(mapping.isEachValueRequired());
			withFalseValues(mapping.getFalseValues());
			withTrueValues(mapping.getTrueValues());
			return this;
		}
		
		public Builder withPattern(String pattern) {
			if(pattern != null && !pattern.trim().isEmpty())
				this.pattern = pattern;
			return this;
		}
		public Builder withLocale(String locale) {
			if(!locale.isEmpty()) {
				try {
					this.locale = LocaleUtils.toLocale(locale);
				} catch (IllegalArgumentException e) {
					throw new CsvParserException("Error on specifying the locale", e);
				}
			}
			return this;
		}
		public Builder withLocale(Locale locale) {
			this.locale = locale;
			return this;
		}
		
		public Builder withSeparator(String separator) {
			this.separator = separator;
			return this;
		}

		public Builder isAllkeeped(boolean keepAll) {
			this.keepAll = keepAll;
			return this;
		}

		public Builder withTrueValues(String... trueValues) {
			this.trueValues = trueValues;
			return this;
		}
		
		public Builder withFalseValues(String... falseValues) {
			this.falseValues = falseValues;
			return this;
		}

		public Builder withTrueValues(List<String> trueValues) {
			this.trueValues = trueValues.toArray(new String[0]);
			return this;
		}
		
		public Builder withFalseValues(List<String> falseValues) {
			this.falseValues = falseValues.toArray(new String[0]);
			return this;
		}

		public Builder isRequired(boolean required) {
			this.required = required;
			return this;
		}
		
		public Builder isTrimed(boolean trim) {
			this.trim = trim;
			return this;
		}

		public Builder isEachValueRequired(boolean eachValueRequired) {
			this.eachValueRequired = eachValueRequired;
			return this;
		}

		public MappingOptions build() {
			return new MappingOptions(this);
		}
	}
	
	private MappingOptions(Builder builder) {
		this.required = builder.required;
		this.trim = builder.trim;
		this.pattern = builder.pattern;
		this.locale = builder.locale;
		this.separator = builder.separator;
		this.keepAll = builder.keepAll;
		this.trueValues = builder.trueValues;
		this.falseValues = builder.falseValues;
		this.eachValueRequired = builder.eachValueRequired;
	}
}
